package io.jft.doll.tcp.handle

import com.g.base.help.d
import io.jft.doll.tcp.TcpC
import io.jft.doll.tcp.event.TcpData
import io.jft.doll.tcp.tcpClient
import io.jft.doll.tcp.utils.BytesUtil
import io.jft.doll.tcp.utils.CRC16
import io.netty.buffer.ByteBuf
import io.netty.channel.ChannelHandlerContext
import io.netty.handler.codec.ByteToMessageDecoder


/**
 * Created by G on 2017/12/25 0025.
 */
class DecoderHandle : ByteToMessageDecoder() {
    override fun decode(ctx: ChannelHandlerContext, inBuf: ByteBuf, outBuf: MutableList<Any>) {
        val beginIndex = inBuf.readerIndex()
        val dataLength = inBuf.readableBytes()

        //不满足最小长度
        if (dataLength < TcpC.HEAD_LENGTH) {
            return
        }

        //协议头不对直接丢弃
        if (inBuf.getInt(beginIndex) != TcpC.PROTOCOL_HEADER.toInt()) {
            inBuf.readerIndex(beginIndex + dataLength)
            return
        }

        //消息体长度
        val bodyLength = inBuf.getShort(beginIndex + 4).toInt() and 0x0FFFF

        //半包
        if (bodyLength > dataLength - TcpC.HEAD_LENGTH) {
            return
        }

        inBuf.readerIndex(beginIndex + bodyLength + TcpC.HEAD_LENGTH)
        val crc = inBuf.getShort(beginIndex + 8).toInt() and 0x0FFFF
        if (CRC16.crcCal(inBuf, beginIndex + TcpC.HEAD_LENGTH, bodyLength) == crc) {
            val command = inBuf.getShort(beginIndex + 6)
            val body = tcpClient.createBuffer()
            inBuf.getBytes(beginIndex + TcpC.HEAD_LENGTH, body, bodyLength)
            outBuf.add(TcpData(command, body))
            d("tcp read Header ${TcpC.comToString(command)}  data ${BytesUtil.bytesToHexString(body.array().sliceArray(IntRange(0, bodyLength)), bodyLength)}")
        }

        //粘包
        if (bodyLength < dataLength - TcpC.HEAD_LENGTH) {
            decode(ctx, inBuf, outBuf)
        }
    }
}